﻿using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;

namespace AuthenticationCenter.Utility
{
    /// <summary>
    /// 非对称加密生成Token
    /// </summary>
    public class CustomRssJWTService : ICustomJWTService
    {
        #region Option注入
        private readonly JWTTokenOption _JWTTokenOptions;
        public CustomRssJWTService(IOptionsMonitor<JWTTokenOption> jwtTokenOptions)
        {
            this._JWTTokenOptions = jwtTokenOptions.CurrentValue;
        }
        #endregion
        public string GetToken(string UserName, string NickName, int Sex, string Role)
        {

            #region 第一步装配有效载荷的数据
            //第一步 装配 有效载荷数据 尽量避免敏感信息 这里是传给鉴权端鉴权时使用的
            var claims = new[]
            {
               new Claim(ClaimTypes.Name, UserName),
               new Claim("NickName",NickName),//要传递给鉴权端的比如说昵称信息  
               new Claim("Role",Role),//要传递给鉴权端端的信息  
               new Claim("Sex",Sex.ToString()),//要传递给鉴权端的信息 
            };
            #endregion


            #region 第二步  生成 JwtSecurityToken 类 用Rsa非对称加密
            string keyDir = Directory.GetCurrentDirectory();

            if (RSAHelper.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams) == false)
            {
                keyParams = RSAHelper.GenerateAndSaveKey(keyDir);
            }

            //1.传入加密秘钥
            SigningCredentials credentials = new SigningCredentials(new RsaSecurityKey(keyParams), SecurityAlgorithms.RsaSha256Signature);

            //3 通过构造函数方式 生成Token
            JwtSecurityToken token = new JwtSecurityToken(issuer: _JWTTokenOptions.Issuer,
                audience: _JWTTokenOptions.Audience,
                claims: claims,
                expires: DateTime.Now.AddMinutes(5),
                signingCredentials: credentials
                );
            #endregion


            #region 第三步 将生成的  JwtSecurityToken类对象 传入 JwtSecurityTokenHandler.WriteToken()函数中生成Token字符串
            //装配 JwtSecurityToken 类这后调用   JwtSecurityTokenHandler.WriteToken 生成Token 字符串
            string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
            #endregion

            return returnToken;
        }
    }
}
